/*
 * File:        hal_frame.c
 * Author:      buquan_chen
 * Comments:    the new framework
 * Data:        2024/01/14
 * Revision history: V0.2
 */
#include "hal_frame.h"
#include "string.h"
// CRC lookup table for quick computation of CRC values
static const unsigned char crc_table[] = {
    0x00,0x31,0x62,0x53,0xc4,0xf5,0xa6,0x97,0xb9,0x88,0xdb,0xea,0x7d,0x4c,0x1f,0x2e,
    0x43,0x72,0x21,0x10,0x87,0xb6,0xe5,0xd4,0xfa,0xcb,0x98,0xa9,0x3e,0x0f,0x5c,0x6d,
    0x86,0xb7,0xe4,0xd5,0x42,0x73,0x20,0x11,0x3f,0x0e,0x5d,0x6c,0xfb,0xca,0x99,0xa8,
    0xc5,0xf4,0xa7,0x96,0x01,0x30,0x63,0x52,0x7c,0x4d,0x1e,0x2f,0xb8,0x89,0xda,0xeb,
    0x3d,0x0c,0x5f,0x6e,0xf9,0xc8,0x9b,0xaa,0x84,0xb5,0xe6,0xd7,0x40,0x71,0x22,0x13,
    0x7e,0x4f,0x1c,0x2d,0xba,0x8b,0xd8,0xe9,0xc7,0xf6,0xa5,0x94,0x03,0x32,0x61,0x50,
    0xbb,0x8a,0xd9,0xe8,0x7f,0x4e,0x1d,0x2c,0x02,0x33,0x60,0x51,0xc6,0xf7,0xa4,0x95,
    0xf8,0xc9,0x9a,0xab,0x3c,0x0d,0x5e,0x6f,0x41,0x70,0x23,0x12,0x85,0xb4,0xe7,0xd6,
    0x7a,0x4b,0x18,0x29,0xbe,0x8f,0xdc,0xed,0xc3,0xf2,0xa1,0x90,0x07,0x36,0x65,0x54,
    0x39,0x08,0x5b,0x6a,0xfd,0xcc,0x9f,0xae,0x80,0xb1,0xe2,0xd3,0x44,0x75,0x26,0x17,
    0xfc,0xcd,0x9e,0xaf,0x38,0x09,0x5a,0x6b,0x45,0x74,0x27,0x16,0x81,0xb0,0xe3,0xd2,
    0xbf,0x8e,0xdd,0xec,0x7b,0x4a,0x19,0x28,0x06,0x37,0x64,0x55,0xc2,0xf3,0xa0,0x91,
    0x47,0x76,0x25,0x14,0x83,0xb2,0xe1,0xd0,0xfe,0xcf,0x9c,0xad,0x3a,0x0b,0x58,0x69,
    0x04,0x35,0x66,0x57,0xc0,0xf1,0xa2,0x93,0xbd,0x8c,0xdf,0xee,0x79,0x48,0x1b,0x2a,
    0xc1,0xf0,0xa3,0x92,0x05,0x34,0x67,0x56,0x78,0x49,0x1a,0x2b,0xbc,0x8d,0xde,0xef,
    0x82,0xb3,0xe0,0xd1,0x46,0x77,0x24,0x15,0x3b,0x0a,0x59,0x68,0xff,0xce,0x9d,0xac
};

struct custom_action_type action = {0};

void write_action(uint8_t action,uint8_t *buf,uint16_t len);

#if HAL_FRAME_ENVIRONMENT

#if HAL_FRAME_DEBUG
#define hal_frame_log_info(x, ...)  printf("[HAL_FRAME]" x " ", ## __VA_ARGS__)
#else
#define hal_frame_log_info(x, ...)
#endif

char *config_readbuf = NULL;
int hal_frame_custom_mode[CUSTOM_MODE_NUM]={mode1,mode2,mode3,mode4,mode5,mode6};

/**
 * @brief Mode data initialization function.
 *
 * This function is used to initialize the mode data, reading the mode data from the configuration file and storing it in the config_readbuf array.
 *
 * @return None
 */
void hal_frame_mode_data_init()
{
    config_readbuf = (char *)(malloc(CUSTOM_MODE_SIZE*CUSTOM_MODE_NUM));
    memset(config_readbuf, 0, sizeof(config_readbuf));

    if(config_readbuf != NULL)
    {
        for (int i = 0; i < CUSTOM_MODE_NUM; i++)
        {
            int res = syscfg_read(hal_frame_custom_mode[i],config_readbuf+CUSTOM_MODE_SIZE*i,CUSTOM_MODE_SIZE);
            hal_frame_log_info("load mode%d len is %d\r\n", i+1, res);
        }
    }
}


/**
 * @brief Retrieves a frame from the config_readbuf array based on the action and offset.
 *
 * This function calculates the address in the config_readbuf array using the provided
 * action and address_offset, reads three bytes from that location, and stores the data
 * in the provided buffer. It then determines the type of frame based on the flags in
 * the first byte of the retrieved data.
 *
 * @param[in]  action    The action identifier used to determine the base address.
 * @param[in]  address_offset The offset added to the base address for the action.
 * @param[out] buf    A pointer to a `union frame_type` where the retrieved frame data
 *                    will be stored.
 *
 * @return A uint8_t indicating the type of frame:
 *         - END_FRAME_TYPE if the frame is an end frame.
 *         - A masked level value if it is a looping frame.
 *         - ACTION_FRAME_TYPE if it is a standard action frame.
 *         Returns 0 if the address is invalid.
 */
static uint8_t get_frame(uint8_t action,uint32_t address_offset,union frame_type *buf)
{
    uint8_t i = 0;
    uint8_t *address = NULL;

    if(config_readbuf == NULL)
    {
        hal_frame_log_info("config_readbuf is null\r\n");
        return 0;
    }
    if (action > 0 || action <= CUSTOM_MODE_NUM)
    {
        address = config_readbuf + CUSTOM_MODE_SIZE*(action-1) + address_offset;
    }
    else
    {
        return 0;
    }

    buf->_data[0] = address[0];
    buf->_data[1] = address[1];
    buf->_data[2] = address[2];

    // hal_frame_log_info("read :");
    // for (i = 0; i < 3; i++)
    // {
    //     hal_frame_log_info("%02X ",buf->_data[i]);
    // }
    // hal_frame_log_info("\r\n");

    if(address[0] & END_MASK)
    {
        return END_FRAME_TYPE;
    }
    if(address[0] & LEVEL_MASK)
    {
        buf->fun_frame.level = address[0];
        buf->fun_frame.next_address = address[1];
        buf->fun_frame.cycle_times = address[2];
        return address[0] &  LEVEL_MASK;  //循环帧
    }
    buf->action_frame.ctrol_set[0] = address[0];
    buf->action_frame.ctrol_set[1] = address[1];
    i = 1;
    if(address[1] & 0x80)
    {
        do{
            i++;
            buf->action_frame.ctrol_set[i] = address[i + 1];
        }while(buf->action_frame.ctrol_set[i] & 0x80);
    }
    buf->action_frame.ctrol_len = i+1;
    buf->action_frame.time = address[2];
    return ACTION_FRAME_TYPE;
}

/**
 * @brief Writes data to flash memory in 1KB chunks.
 *
 * @param address The starting address of the flash memory block to write to.
 * @param buf The data to be written to flash memory.
 * @param len The length of the data to be written in bytes.
 *
 * @note This function writes the data in 1KB chunks by calling syscfg_write() with
 *       a length of 1024 bytes. If the length of the data is not a multiple of 1024,
 *       the remaining bytes will be padded with zeros.
 */
static void flash_write_1k(uint32_t address,uint8_t *buf,uint16_t len)
{
    // syscfg_write(address,buf,1024);
    int res = syscfg_write(address,buf,len);;
    hal_frame_log_info("write sys_cfg_id %d, len is %d\r\n", address, res);
}

/**
 * @brief Writes data to flash memory with left alignment and padding.
 *
 * This function reads the existing data from the specified flash memory
 * address into a buffer, then copies the provided data into the buffer,
 * left-aligning it. It pads the remaining space in the buffer with zeros
 * to ensure alignment. Finally, it writes the entire buffer back to the
 * flash memory.
 *
 * @param address The starting address of the flash memory block to write to.
 * @param buf A pointer to the data to be written to flash memory.
 * @param len The length of the data to be written in bytes.
 *
 * @note The function reads 1024 bytes from the flash memory, allowing for
 *       a buffer size that is twice the alignment value to accommodate
 *       the new data and padding.
 */
static void flash_write_left(uint32_t address,uint8_t *buf,uint16_t len)
{
    uint16_t offset = 0;
    uint16_t left = len;
    uint16_t aligned_len = 512; // Round up to the nearest multiple of 512
    uint8_t padded_buf[aligned_len*2];
    syscfg_read(address,padded_buf,1024);
    
    memcpy(padded_buf,buf,len);

    memset(padded_buf+len,0,aligned_len-len);   // Padding with zeros

    syscfg_write(address,padded_buf,1024);
}

/**
 * @brief Writes data to flash memory with right alignment and padding.
 *
 * This function reads the existing data from the specified flash memory
 * address into a buffer, then copies the provided data into the buffer,
 * right-aligning it. It pads the remaining space in the buffer with zeros
 * to ensure alignment. Finally, it writes the entire buffer back to the
 * flash memory.
 *
 * @param address The starting address of the flash memory block to write to.
 * @param buf A pointer to the data to be written to flash memory.
 * @param len The length of the data to be written in bytes.
 *
 * @note The function reads 1024 bytes from the flash memory, allowing for
 *       a buffer size that is twice the alignment value to accommodate
 *       the new data and padding.
 */
static void flash_write_right(uint32_t address,uint8_t *buf,uint16_t len)
{
    uint16_t offset = 0;
    uint16_t left = len;
    uint16_t aligned_len = 512; // Round up to the nearest multiple of 512
    uint8_t padded_buf[aligned_len*2];
    syscfg_read(address,padded_buf,1024);
    
    memcpy(padded_buf+512,buf,len);

    memset(padded_buf+512+len,0,aligned_len-len);   // Padding with zeros

    syscfg_write(address,padded_buf,1024);
}
#ifdef CONFIG_BOARD_7916AB  //use AC79
void write_action(uint8_t action,uint8_t *buf,uint16_t len)
{
    if (action>0 && action <= CUSTOM_MODE_NUM)
    {
        flash_write_1k(hal_frame_custom_mode[action-1],buf,len);
        int res = syscfg_read(hal_frame_custom_mode[action-1],config_readbuf+(action-1)*CUSTOM_MODE_SIZE,CUSTOM_MODE_SIZE);
        hal_frame_log_info("read mode %d, len is %d\r\n", action, res);
    }
    else
    {
        hal_frame_log_info("write action error\r\n");
    }
}
#else   //use AC69
void write_action(uint8_t action,uint8_t *buf,uint16_t len)
{
    if (action>0 && action <= CUSTOM_MODE_NUM)
    {
        if (action%2 == 1)
        {
            flash_write_left(hal_frame_custom_mode[action-1],buf,len);
        }
        else
        {
            flash_write_right(hal_frame_custom_mode[action-1],buf,len);
        }
        int res = syscfg_read(hal_frame_custom_mode[action-1],config_readbuf+(action-1)*CUSTOM_MODE_SIZE,CUSTOM_MODE_SIZE);
        hal_frame_log_info("read mode %d, len is %d\r\n", action, res);
    }
    else
    {
        hal_frame_log_info("write action error\r\n");
    }
}

#endif
#else

#if HAL_FRAME_DEBUG
#define hal_frame_log_info(X...) printf(X)
#else
#define hal_frame_log_info(X...)
#endif

/**
 * @brief Writes data to flash memory.
 *
 * This function writes a specified length of data from a buffer to a given
 * flash memory address.
 *
 * @param address The starting address in flash memory where data will be written.
 * @param buf A pointer to the buffer containing the data to be written.
 * @param len The number of bytes to write from the buffer to flash memory.
 */
static void flash_write(uint32_t address,uint8_t *buf,uint16_t len)
{
    //Implementing writting data
}

/**
 * @brief Reads data from flash memory.
 *
 * This function reads a specified length of data from a given flash memory
 * address into a buffer.
 *
 * @param address The starting address in flash memory where data will be read.
 * @param buf A pointer to the buffer that will store the data read from flash
 *            memory.
 * @param len The number of bytes to read from flash memory into the buffer.
 */
static void flash_read(uint32_t address,uint8_t *buf,uint16_t len)
{
    //Implementing reading data
}

/**
 * @brief Retrieves a frame from flash memory based on action and offset.
 *
 * This function calculates the address in flash memory using the provided 
 * action and address_offset, reads three bytes from that location, and stores 
 * the data in the provided buffer. It then determines the type of frame based 
 * on the flags in the first byte of the retrieved data.
 *
 * @param action The action identifier used to determine the base address.
 * @param address_offset The offset added to the base address for the action.
 * @param buf A pointer to a `union frame_type` where the retrieved frame data 
 *            will be stored.
 * 
 * @return A uint8_t indicating the type of frame:
 *         - END_FRAME_TYPE if the frame is an end frame.
 *         - A masked level value if it is a looping frame.
 *         - ACTION_FRAME_TYPE if it is a standard action frame.
 *         Returns 0 if the address is invalid.
 */
static uint8_t get_frame(uint8_t action,uint32_t address_offset,union frame_type *buf)
{
    uint8_t i;
    uint32_t address = 0;
    uint8_t tmp_data[4];

    if (action > 0 || action <= CUSTOM_MODE_NUM)
    {
        address = custom_mode_based_adress + CUSTOM_MODE_SIZE*(action-1) + address_offset;
    }
    else
    {
        return 0;
    }

    flash_read(address,&tmp_data[0],3);
    buf->_data[0] = tmp_data[0];
    buf->_data[1] = tmp_data[1];
    buf->_data[2] = tmp_data[2];

    if(tmp_data[0] & END_MASK)
    {
        return END_FRAME_TYPE;
    }
    if(tmp_data[0] & LEVEL_MASK)
    {
        buf->fun_frame.level = tmp_data[0];
        buf->fun_frame.next_address = tmp_data[1];
        buf->fun_frame.cycle_times = tmp_data[2];
        return tmp_data[0] &  LEVEL_MASK;  //循环帧
    }
    buf->action_frame.ctrol_set[0] = tmp_data[0];
    buf->action_frame.ctrol_set[1] = tmp_data[1];
    i = 1;
    if(tmp_data[1] & 0x80)
    {
        do{
            i++;
            flash_read(address+i+1,&buf->action_frame.ctrol_set[i],1);
        }while(buf->action_frame.ctrol_set[i] & 0x80);
    }
    buf->action_frame.ctrol_len = i+1;
    buf->action_frame.time = tmp_data[2];
    return ACTION_FRAME_TYPE;
}

/**
 * @brief Writes a sequence of bytes to flash memory based on action.
 *
 * This function uses the provided action identifier to determine the base
 * address for the write operation. It then calls the underlying flash write
 * function to write the data to flash memory.
 *
 * @param action The action identifier used to determine the base address.
 * @param buf A pointer to a buffer containing the data to be written.
 * @param len The length of the data in the buffer.
 */
void write_action(uint8_t action, uint8_t *buf, uint16_t len)
{
    if (action>0 && action <= CUSTOM_MODE_NUM)
    {
        flash_write(custom_mode_based_adress + CUSTOM_MODE_SIZE*(action-1), buf, len);
        hal_frame_log_info("write mode %d\r\n", action);
    }
    else
    {
        hal_frame_log_info("write action error\r\n");
    }

}

#endif

/**
 * @brief Gets the next action byte sequence based on the action id.
 *
 * This function uses the provided action id to determine the base address
 * for the read operation. It then calls the underlying flash read function to
 * read the data from flash memory and stores it in the provided buffer.
 *
 * @param[out] ctrol_object A pointer to a buffer where the action byte sequence
 *                           will be stored.
 *
 * @return  0 if the action id is 0, 1 if successful, otherwise return 0.
 * @see     hal_frame_set_action, hal_frame_get_action_id
 */
uint8_t hal_frame_get_ation(uint8_t *ctrol_object)
{
    uint8_t type = 0;
    int i = 0;
    if(action.action_id == 0) return 0;
    again:
    type = get_frame(action.action_id,action.nxt_address,&action.frame);
    if(type == ACTION_FRAME_TYPE)
    {
        for(i=0;i < action.frame.action_frame.ctrol_len+1;i++)
        {
            ctrol_object[i] = action.frame.action_frame.ctrol_set[i];
        }
        if(++action.level0_times ==  action.frame.action_frame.time)
        {
            action.nxt_address += ACTION_BYTE;
            action.level0_times = 0;
        }
    }
    else
    {
        if(type == CYCLE01_FRAME_TYPE)
        {
            if(++action.level1_times < action.frame.fun_frame.cycle_times)
            {
                action.nxt_address = action.frame.fun_frame.next_address | ((action.frame.fun_frame.level & CYCLE_OVER_TYPE) << 8);
            }
            else
            {
                action.level1_times = 0;
                action.nxt_address += 3;
            }
            goto again;
        }
        else if(type == CYCLE02_FRAME_TYPE)
        {
            if(++action.level2_times < action.frame.fun_frame.cycle_times)
            {
                action.nxt_address = action.frame.fun_frame.next_address | ((action.frame.fun_frame.level & CYCLE_OVER_TYPE) << 8);
            }
            else
            {
                action.level2_times = 0;
                action.nxt_address += 3;
            }
            goto again;
        }
        else if(type == CYCLE03_FRAME_TYPE)
        {
            if(++action.level3_times < action.frame.fun_frame.cycle_times)
            {
                action.nxt_address = action.frame.fun_frame.next_address | ((action.frame.fun_frame.level & CYCLE_OVER_TYPE) << 8);
            }
            else
            {
                action.level3_times = 0;
                action.nxt_address += 3;
            }
            goto again;
        }
    else if(type == END_FRAME_TYPE)  
        {
            action.action_id = 0;
            return 0;
        }
    }
    return 1;
}
/**
 * @brief   Initialize the custom action data structure
 *
 * @details This function initializes all fields of the custom action data structure to zero.
 *          It is called at the beginning of the program to reset the data structure.
 *
 * @see     hal_frame_get_ation, hal_frame_set_action, hal_frame_analy_recv
 */
void hal_frame_action_init(void)
{
    action.level0_times = 0;
    action.level1_times = 0;
    action.level2_times = 0;
    action.level3_times = 0;

    action.action_id = 0;
    action.nxt_address = 0;

    action.frame._data[0] = 0;
    action.frame._data[1] = 0;
    action.frame._data[2] = 0;
    hal_frame_log_info(" init action\r\n");
}

/**
 * @brief   Set the action id to the custom action data structure
 *
 * @details This function sets the action id to the custom action data structure
 *          and resets all other fields of the data structure to zero.
 *
 * @param[in]   id         The action id to set
 *
 * @see     hal_frame_get_ation, hal_frame_action_init
 */
void hal_frame_set_action(uint8_t id)
{
    action.level0_times = 0;
    action.level1_times = 0;
    action.level2_times = 0;
    action.level3_times = 0;

    action.action_id = id;
    action.nxt_address = 0;

    action.frame._data[0] = 0;
    action.frame._data[1] = 0;
    action.frame._data[2] = 0;
    hal_frame_log_info("set action id = %u\r\n",action.action_id);
}

/**
 * @brief   Get the current action id
 *
 * @details This function returns the current action id stored in the custom action
 *          data structure. The action id is set by the function hal_frame_set_action.
 *
 * @return  The current action id
 *
 * @see     hal_frame_set_action, hal_frame_get_ation
 */
uint8_t hal_frame_get_action_id(void)
{
    return action.action_id;
}

/**
 * @brief   Analyze a frame received from the phone and store the frame data
 *          to the corresponding custom mode
 *
 * @details This function analyzes a frame received from the phone and stores the
 *          frame data to the corresponding custom mode. The first byte of the
 *          frame data is used to determine the custom mode to write to.
 *
 * @param[in]  buf    Pointer to the frame data
 * @param[in]  len    Length of the frame data
 *
 * @see     write_action
 */
void hal_frame_protocol_analy(uint8_t *buf,uint16_t len)
{
    if (buf[0]>0 && buf[0] <= CUSTOM_MODE_NUM)
    {
        write_action(buf[0],&buf[1],len - 1);
    }
    else
    {
        hal_frame_log_info("invalid action id, overflow\r\n");
    }
}

/**
 * @brief      Calculate the CRC for the given buffer
 *
 * @param[in]  buf   Pointer to the data buffer
 * @param[in]  len   Length of the data buffer
 *
 * @return     The calculated CRC value
 *
 * @details    This function computes the CRC by iterating over each byte in the
 *             provided buffer and updating the CRC value using a predefined
 *             CRC table. The function returns the final CRC value.
 */
uint8_t hal_frame_crc(uint8_t *buf,uint16_t len)
{
    uint8_t  crc = 0x00;
 
    while (len--)
    {
        crc = crc_table[crc ^ *buf];
              buf++;
    }
    return crc;
}

uint8_t send_data(uint8_t *buf,uint16_t len)
{
}

/**
 * @brief      Send a packet to the phone
 *
 * @param[in]  commandType  Type of command to send
 * @param[in]  data         Data to send
 * @param[in]  dataLength   Length of the data to send
 *
 * @details    This function constructs a packet with the given command type and
 *             data, calculates the CRC, and sends the packet over the
 *             communication channel.
 */
void hal_frame_send_data(uint8_t commandType, uint8_t *data, uint16_t dataLength)
{
    uint8_t packet[32] = {0};
    uint16_t index = 0;

    packet[index++] = 0x51;
    packet[index++] = 0x98;

    // key_index = (key_index + 1) % 4;
    // packet[index++] = key_index; // Key index placeholder

    packet[index++] = 0x00; // unused

    // Increase the sequence number and wrap around if it exceeds 255
    // last_sequence_number = (last_sequence_number + 1) % 256;
    // packet[index++] = last_sequence_number; // Sequence number

    packet[index++] = 0x00; // unused

    packet[index++] = 0x00; // Device type
    packet[index++] = 0x00; // Device ID
    packet[index++] = 0x02; // Direction (0x01: to device, 0x02: to phone)
    packet[index++] = 0x00; // CRC
    packet[index++] = commandType;
    packet[index++] = dataLength >> 8;
    packet[index++] = dataLength&0xFF;


    memcpy(&packet[index], data, dataLength);
    index += dataLength;

    // Calculate CRC
    uint8_t crc = hal_frame_crc(&packet[8], dataLength); // Polynomial 0x31
    packet[7] = crc;

    hal_frame_log_info("Sending packet: ");
    for (int i = 0; i < index; i++) {
        hal_frame_log_info("%02X ", packet[i]);
    }
    hal_frame_log_info("\r\n");

    send_data(packet, index);
}

/**
 * @brief      Analyze a frame received from the phone
 *
 * @param[in]  pValue  Pointer to the frame data
 * @param[in]  len     Length of the frame data
 *
 * @return     None
 *
 * @details    This function verifies the frame header, checks the CRC, and extracts
 *             the fields from the packet. It then processes the command based on
 *             the command type. If the command is unknown, it prints an error message.
 */
//void hal_frame_analy_recv(uint8_t *pValue, uint16_t len)
//{
//    uint8_t datatemp[32] = {0};
//    if (len < 11) return; // Minimum length to include header, length, command, data, CRC
//
//    // Check packet header
//    if (pValue[0] != 0x51 || pValue[1] != 0x98) return;
//
//    uint8_t crc = pValue[7];
//    // Calculate CRC over data from index 9 to the end
//    uint8_t calculatedCrc = hal_frame_crc(&pValue[8], len - 8); // Polynomial 0x31
//
//    if (crc != calculatedCrc)
//    {
//        hal_frame_log_info("CRC mismatch\r\n");
//        // datatemp[0] = errorcode;
//        // hal_frame_send_data(0xfe,datatemp,1);    //send error msg
//        return; // CRC mismatch
//    }
//
//    // Extract fields from the packet
//    uint8_t keyIndex = pValue[2];
//    uint8_t sequence = pValue[3];
//    uint8_t deviceType = pValue[4];
//    uint8_t deviceId = pValue[5];
//    uint8_t direction = pValue[6];
//    uint8_t commandType = pValue[8];
//    uint16_t dataLength = pValue[9]<<8 | pValue[10];
//    uint8_t *data = &pValue[11];
//
//    if (len != 11 + dataLength)
//    {
//        hal_frame_log_info("Data length mismatch\r\n");
//        // datatemp[0] = errorcode;
//        // hal_frame_send_data(0xfe,datatemp,1);    //send error msg
//        return;
//    }
//
//    // Update the last received sequence number
//    // last_sequence_number = sequence;
//    // keyIndex = key_index;
//
//    // Process command
//    switch (commandType) {
//        case 0x00:
//            // Handle command 0x00
//            hal_frame_protocol_analy(data,len);
//
//            datatemp[0] = 1;
//            hal_frame_send_data(0xff,datatemp,1);
//            hal_frame_log_info("Command 0x00 received with data length %d\n", dataLength);
//            break;
//        default:
//            // Unknown command
//            hal_frame_log_info("Unknown command 0x%02X received\n", commandType);
//            break;
//    }
//}
/*
void main(void)
{
    hal_frame_action_init();
    hal_frame_mode_data_init(); //only for JL chip

    //step 1: update frame data, see the function hal_frame_protocol_analy

    //step 2: set action, when user change mode, call hal_frame_set_action
    hal_frame_set_action(1);
    uint8_t mode_data[ACTION_BYTE-1];
    //step 3: get frame action, and change the machine state
    while(1)
    {
        if(hal_frame_get_ation(mode_data)){
            app_action_change(mode_data);           //your code
        }
        else
        {
            //do something
        }

        //Requires a delay, depending on the action interval
    }
}

void app_action_change(uint8_t* ans)
{

    if(ans[0] & XXXX_TYPE)
    {
        //do something
    }
    else
    {
        //do something
    }
    if (ans[1] & XXXX_TYPE)
    {
        //do something
    }
    else
    {
        //do something
    }

}
*/

